/*
 *  Copyright (C) 2006 Takeharu KATO
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <gnome.h>
#include <glib.h>
#include <gconf/gconf-client.h>
#include "callbacks.h"
#include "interface.h"
#include "support.h"

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include "common.h"

static char *hexstr = "0123456789abcdef";
static int 
get_hexstr_index(const char ch,char *index){
  char *found=NULL;
  char ind = 0;
  int search_ch = 0;

  search_ch = tolower((int)ch);

  found=strchr(hexstr,(int)search_ch);
  if (found == NULL) {
    err_out("Character %c(%c in original message) can not be found.\n",
	    search_ch, ch);
    return -ESRCH;
  }

  ind=(char)(found - hexstr);

#if 0
  dbg_out("%c is %d th\n", ch, ind);
#endif

  *index = ind;

  return 0;
}
int
print_hex(const char *buff,size_t len){
  int i;
  dbg_out("decode-in-hex:");
  for (i=0;i<len;++i) {
    dbg_out("%x",buff[i]>>4);
    dbg_out("%x",buff[i]&0xf);
  }
  dbg_out("\n");
}
static int
parse_encoded_message(const unsigned char *message,
		      unsigned long *this_cap_p,
		      unsigned char **hex_skey_p,
		      unsigned char **enc_message_p,
		      unsigned char **hex_sign_p){
  int rc;
  char *sp,*ep;
  unsigned long this_cap;
  unsigned char *hex_skey=NULL;
  unsigned char *enc_message=NULL;
  unsigned char *hex_sign=NULL;
  char *buff=NULL;

  if ( (!message) || (!this_cap_p) || (!hex_skey_p) || (!enc_message_p) )
    return -EINVAL;

  rc=-ENOMEM;
  buff=g_strdup(message);
  if (!buff)
    goto error_out;
  /*
   *鍵情報
   */
  sp=buff;
  ep=strchr(sp,':');
  if (!ep) {
    rc=-EINVAL;
    err_out("Error : No cap\n");
    goto free_buff_out;
  }
  *ep='\0';
  ++ep;
  errno=0;
  this_cap=strtoul(sp, (char **)NULL, 16);
  dbg_out("Cap:0x%x\n",this_cap);
  /*
   *暗号鍵
   */
  sp=ep;
  ep=strchr(sp,':');
  if (!ep) {
    rc=-EINVAL;
    err_out("Error : crypt key\n");
    goto free_buff_out;
  }
  *ep='\0';
  ++ep;
  rc=-ENOMEM;
  hex_skey=g_strdup(sp);
  if (!hex_skey)
    goto free_buff_out;
  dbg_out("hex secret key:%s\n",hex_skey);

  /*
   *暗号化本文
   */
  sp=ep;
  ep=strchr(sp,':');
  if (ep) { /* これで最後の可能性もある  */
    *ep='\0';
    ++ep;
  }
  rc=-ENOMEM;
  enc_message=g_strdup(sp);
  if (!enc_message)
    goto free_hex_skey_out;
  dbg_out("hex secret body:%s\n",enc_message);

  /*
   *署名
   */
  if (ep) {
    sp=ep;
    rc=-ENOMEM;
    hex_sign=g_strdup(sp);
    if (!hex_sign)
      goto free_enc_message_out;
    dbg_out("hex sign:%s\n",hex_sign);
  }
  *this_cap_p=this_cap;
  *hex_skey_p=hex_skey;
  *enc_message_p=enc_message;
  *hex_sign_p=hex_sign;
  if (buff)
    g_free(buff);
  return 0;
 free_enc_message_out:
  if (enc_message)
    g_free(enc_message);
 free_hex_skey_out:
  if (hex_skey)
    g_free(hex_skey);
 free_buff_out:
  if (buff)
    g_free(buff);
 error_out:
  return rc;
}
static int
string_bin2hex(const u_int8_t *bindata, int len,unsigned char **ret_p)
{
  int rc;
  int i;
  size_t buf_len;
  unsigned char *buff=NULL;
  unsigned char *buff_p=NULL;

  if ( (!bindata) || (!ret_p) )
    return -EINVAL;

  buf_len=len*2+1;

  rc=-ENOMEM;
  buff=g_malloc(buf_len);
  if (!buff)
    goto error_out;

  memset(buff,0,buf_len);
  
  for (i=0,buff_p=buff; i < len; ++i)
    {
      *buff_p++ = hexstr[bindata[i] >> 4];
      *buff_p++ = hexstr[bindata[i] & 0x0f];
    }
  *buff_p = 0;

  rc=0;
  *ret_p=buff;

 error_out:
  return rc;
}

static int
string_hex2bin(const char *hexdata, int *len,unsigned char **ret_p)
{
  int rc;
  int i;
  size_t data_len;
  size_t buf_len;
  unsigned char *buff=NULL;
  unsigned char *buff_p=NULL;
  char low,high;

  data_len=strlen(hexdata);
  buf_len=data_len/2;

  rc=-ENOMEM;
  buff=g_malloc(buf_len);
  if (!buff)
    goto error_out;

  memset(buff,0,buf_len);

  for (i=0,buff_p=buff; (((i+1) < data_len)&&(hexdata[i]) && (hexdata[i+1])); )
    {
      rc=get_hexstr_index(hexdata[i++],&high);
      if (rc)
	goto error_out;
      rc=get_hexstr_index(hexdata[i++],&low);
      if (rc)
	goto error_out;
      *buff_p++ = ( ( (high << 4) & 0xf0)|(low & 0xf));
    }
  

  *ret_p=buff;
  *len=buf_len;

  return 0;

 error_out:
  if (buff)
    g_free(buff);
  return rc;
}
int
ipmsg_encrypt_message(const char *peer_addr,const char *message,unsigned char **ret_str,size_t *len){
  int rc;
  int retry;
  unsigned long peer_cap;
  unsigned long skey_type,akey_type;
  char *session_key=NULL;
  char *enc_skey=NULL;
  size_t skey_len;
  char *key_e=NULL,*key_n=NULL;
  char *raw_enc_body=NULL;
  unsigned char *enc_body=NULL;
  size_t enc_len;
  unsigned char *encrypted_message=NULL;
  size_t total_len;
  unsigned char *sign=NULL;
  unsigned long sign_type;

  if ( (!peer_addr) || (!message) || (!ret_str) || (!len) )
    return -EINVAL;

  /*  相手の暗号化能力を取得  */
  retry=PUBKEY_MAX_RETRY;
  do{
    rc=userdb_wait_public_key(peer_addr,&peer_cap,&key_e,&key_n);
    if ( (rc<0) && (rc != -EINTR) )
      return rc; /* 明示的なエラー */
    if (!rc) {
      /* 見付けた */
      dbg_out("Found: \n\taddr=%s\ncap=%x\tpubkey-e=%s\n\tpubkey-n=%s\n",
	      peer_addr,
	      peer_cap,
	      key_e,
	      key_n);

      break; 
    }
    --retry;
  }while(retry);
  
  if ( (rc) && (!retry) )
    goto free_peer_key_out;

  /*
   *暗号化アルゴリズムを選択
   */
  rc=select_symmetric_key(peer_cap,
			  &skey_type,
			  hostinfo_refer_ipmsg_crypt_policy_is_speed());
  if (rc)
    goto free_peer_key_out;
  
  /*
   * セッションキー作成と本文の暗号化
   */
  rc=symcrypt_encrypt_message(skey_type,message,&session_key,
			      &skey_len,&raw_enc_body,&enc_len);
  if (rc)
    goto free_peer_key_out;

  rc=string_bin2hex((const u_int8_t *)raw_enc_body, enc_len,&enc_body);
  if (rc)
    goto free_session_key_out;    

  /*
   * セッションキーを暗号化
   */
  rc=pcrypt_encrypt_message(peer_cap,key_e,key_n,session_key,skey_len,&enc_skey,&akey_type);
  if (rc)
    goto free_enc_body_out;

  total_len=sizeof(unsigned long)*2+strlen(enc_skey)+strlen(enc_body)+3;

  rc=-ENOMEM;
  encrypted_message=g_malloc(total_len);
  if (!encrypted_message)
    goto free_encoded_session_key;
  /* 
   *署名を選択する
   */
  if (peer_cap & SIGN_CAPS) {
    if (peer_cap & IPMSG_SIGN_MD5)
      sign_type=IPMSG_SIGN_MD5;
    if (peer_cap & IPMSG_SIGN_SHA1)
      sign_type=IPMSG_SIGN_SHA1;
  }else{
    sign_type=0; /*  署名を使用しない  */
  }
  snprintf(encrypted_message,total_len,"%x:%s:%s",(skey_type|akey_type|sign_type),enc_skey,enc_body);
  dbg_out("Encrypted body:%s\n",encrypted_message);
  /*  FIXME 署名を選ぶ処理を分離すること  */
  if (peer_cap & SIGN_CAPS) {
    rc=pcrypt_sign(akey_type,sign_type,encrypted_message, &sign);
    if (rc)
      goto free_sign_out;
    /*  本文を再作成  */
    g_free(encrypted_message);
    total_len += (strlen(sign)+3);
    encrypted_message=g_malloc(total_len);
    if (!encrypted_message)
      goto free_sign_out;
    snprintf(encrypted_message,total_len,"%x:%s:%s:%s",
	     (skey_type|akey_type|sign_type),
	     enc_skey,
	     enc_body,
	     sign);
    dbg_out("Signed body:%s\n",encrypted_message);
  }
  *ret_str=encrypted_message;
  *len=strlen(encrypted_message);

  rc=0;
 free_sign_out:
  if (sign)
    g_free(sign);
 free_enc_body_out:
  if (enc_body)
    g_free(enc_body);
 free_encoded_session_key:
  if (enc_skey)
    g_free(enc_skey);
 free_session_key_out:
  if (session_key)
    g_free(session_key);
  if (raw_enc_body)
    g_free(raw_enc_body);
 free_peer_key_out:
  if (key_e)
    g_free(key_e);
  if (key_n)
    g_free(key_n);

 error_out:
  return rc;
}
int
ipmsg_decrypt_message(const char *peer_addr,const char *message,unsigned char **ret_str,size_t *len){
  int rc;
  unsigned long this_cap;
  unsigned char *hex_skey=NULL;
  char *skey=NULL;
  unsigned char *signed_message=NULL;
  unsigned char *end_message_body_p=NULL;
  unsigned char *enc_message=NULL;
  unsigned char *hex_sign=NULL;
  unsigned long skey_type,akey_type;
  unsigned long sign_type;
  unsigned char *enc_bin_body=NULL;
  unsigned char *peer_key_e=NULL;
  unsigned char *peer_key_n=NULL;
  unsigned long tmp_cap;
  unsigned long new_flags;
  char *plain=NULL;
  size_t plain_len;
  size_t skey_len;
  size_t enc_bin_len;
  
  if ( (!message) || (!ret_str) || (!len) )
    return -EINVAL;

  rc=parse_encoded_message(message,
			   &this_cap,
			   &hex_skey,
			   &enc_message,
			   &hex_sign);
  if (rc) {
    err_out("Can not parse message\n");
    goto error_out;
  }
  /*
   * 暗号化に使用した鍵を取得
   */
  skey_type=get_symkey_part(this_cap);  /* 共通鍵 */
  akey_type=get_asymkey_part(this_cap); /* 公開鍵 */
  sign_type=get_sign_part(this_cap);
  dbg_out("Cap:%x Skey:%x AKey:%x Sign:%x\n",this_cap,skey_type,akey_type,sign_type);
  /*
   *署名がある場合は署名を検証
   */
  g_assert(peer_addr); /* udpからの呼出しの場合はかならずいれる  */
  if ( (hostinfo_get_ipmsg_crypt_capability() & sign_type) && (hex_sign) ) {
    dbg_out("This message is signed by peer.\n");
    /*
     *相手の公開鍵を取得
     */
    rc=userdb_get_public_key_by_addr(peer_addr,&tmp_cap,(char **)&peer_key_e,(char **)&peer_key_n);
    if (rc)
      goto free_parsed_datas;

    /* 編集用にコピー  */
    signed_message=g_strdup(message);
    rc=-ENOMEM;
    if (!signed_message)
      goto free_parsed_datas;
    end_message_body_p=strrchr(signed_message,':');
    if (!end_message_body_p) /*  異常データ  */
      goto free_parsed_datas;
    *end_message_body_p='\0'; /* 本文だけを参照  */
    dbg_out("Verify:%s with %s\n",signed_message,hex_sign);
    rc=pcrypt_verify_sign(this_cap,sign_type,signed_message, 
			  hex_sign,peer_key_e,peer_key_n);
    /*  失敗した場合でも, 不要なデータを開放してからぬける  */
    if (rc) {
      err_out("Verify failed:rc=%d\n",rc);
      goto free_parsed_datas;
    }
    dbg_out("Verify OK\n");
  }

  /*
   *共通鍵をデコード
   */
  /* FIXME 鍵のバリデーション(RSAが2つ以上設定されていないか) */
  rc=pcrypt_decrypt_message(akey_type,hex_skey,&skey,&skey_len);
  if (rc)
    goto free_parsed_datas;
  dbg_out("Decrypt key len:%d\n",skey_len);
  /*
   *暗号化された本文のバイナリ化
   */
  rc=string_hex2bin(enc_message,&enc_bin_len, &enc_bin_body);
  if (rc)
    goto free_skey;

#if 0
  print_hex(skey,skey_len);
#endif

  rc=symcrypt_decrypt_message(skey_type,enc_bin_body,enc_bin_len,
			      skey,&plain,&plain_len);
  if (rc)
    goto free_enc_bin_body;
  dbg_out("Decoded:%s len=%d\n",plain,plain_len);
  *ret_str=plain;
  *len=plain_len;
  rc=0;
 free_enc_bin_body:
  if (enc_bin_body)
    g_free(enc_bin_body);
 free_skey:
  if (skey)
    g_free(skey);
 free_parsed_datas:
  if (hex_skey)
    g_free(hex_skey);
  if (enc_message)
    g_free(enc_message);
  if (hex_sign)
    g_free(hex_sign);
  if (peer_key_e)
    g_free(peer_key_e);
  if (peer_key_n)
    g_free(peer_key_n);
  if (signed_message)
    g_free(signed_message);

 error_out:
  if (rc != 0) {
    new_flags = hostinfo_get_normal_entry_flags();
    new_flags &= ~IPMSG_ENCRYPTOPT;  /* 暗号化通信不可能であることを通知する  */
    ipmsg_send_gratuitous_ans_entry(udp_con, peer_addr, new_flags);
    ipmsg_err_dialog(_("Can not decode message from %s rc = %d"), peer_addr, rc);
  }
  return rc;
}

GtkWidget *
internal_create_crypt_config_window(void){
  int rc;
  GtkWidget *configWindow;
  GtkWidget *sendHostListChkBtn;
  GtkWidget *obtainHostlistChkBtn;
  GtkWidget *configRC2Bit40Btn;
  GtkWidget *configRC2Bit128Btn;
  GtkWidget *configRC2Bit256Btn;
  GtkWidget *configBFBit128Btn;
  GtkWidget *configBFBit256Btn;
  GtkWidget *configRSABit512Btn;
  GtkWidget *configRSABit1024Btn;
  GtkWidget *configRSABit2048Btn;
  GtkWidget *configMD5Btn;
  GtkWidget *configSHA1Btn;
  GtkWidget *keySelectAlgoCBtn;
  GtkWidget *RSAKeyEncryptionCBtn;
  GtkWidget *useLockCBtn;
  unsigned long state;
  
  configWindow=create_securityConfig ();
  g_assert(configWindow);

  sendHostListChkBtn=lookup_widget(configWindow,"sendHostListChkBtn");
  obtainHostlistChkBtn=lookup_widget(configWindow,"obtainHostlistChkBtn");
  configRC2Bit40Btn=lookup_widget(configWindow,"configRC2Bit40Btn");
  configRC2Bit128Btn=lookup_widget(configWindow, "configRC2Bit128Btn");
  configRC2Bit256Btn=lookup_widget(configWindow, "configRC2Bit256Btn");
  configBFBit128Btn=lookup_widget(configWindow, "configBFBit128Btn");
  configBFBit256Btn=lookup_widget(configWindow, "configBFBit256Btn");
  configRSABit512Btn=lookup_widget(configWindow, "configRSABit512Btn");
  configRSABit1024Btn=lookup_widget(configWindow, "configRSABit1024Btn");
  configRSABit2048Btn=lookup_widget(configWindow, "configRSABit2048Btn");
  configMD5Btn=lookup_widget(configWindow, "configMD5Btn");
  configSHA1Btn=lookup_widget(configWindow, "configSHA1Btn");
  keySelectAlgoCBtn=lookup_widget(configWindow, "keySelectAlgoCBtn");
  RSAKeyEncryptionCBtn=lookup_widget(configWindow, "RSAKeyEncryptionCBtn");
  useLockCBtn=lookup_widget(configWindow, "useLockCBtn");


  rc=hostinfo_refer_ipmsg_cipher(&state);
  if (rc)
    return;

  /*
   *ホストリスト制御
   */
  if (hostinfo_refer_ipmsg_is_allow_hlist())
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sendHostListChkBtn),TRUE);
  else
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sendHostListChkBtn),FALSE);

  if (hostinfo_refer_ipmsg_is_get_hlist())
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(obtainHostlistChkBtn),TRUE);
  else
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(obtainHostlistChkBtn),FALSE);

  /*
   *暗号選択
   */
  if (state & IPMSG_RC2_40)
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(configRC2Bit40Btn),TRUE);
  else
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(configRC2Bit40Btn),FALSE);

  if (state & IPMSG_RC2_128)
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(configRC2Bit128Btn),TRUE);
  else
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(configRC2Bit128Btn),FALSE);

  if (state & IPMSG_RC2_256)
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(configRC2Bit256Btn),TRUE);
  else
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(configRC2Bit256Btn),FALSE);

  if (state & IPMSG_BLOWFISH_128)
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(configBFBit128Btn),TRUE);
  else
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(configBFBit128Btn),FALSE);

  if (state & IPMSG_BLOWFISH_256)
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(configBFBit256Btn),TRUE);
  else
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(configBFBit256Btn),FALSE);

  if (state & IPMSG_RSA_512)
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(configRSABit512Btn),TRUE);
  else
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(configRSABit512Btn),FALSE);

  if (state & IPMSG_RSA_1024)
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(configRSABit1024Btn),TRUE);
  else
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(configRSABit1024Btn),FALSE);

  if (state & IPMSG_RSA_2048)
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(configRSABit2048Btn),TRUE);
  else
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(configRSABit2048Btn),FALSE);

  if (state & IPMSG_SIGN_MD5)
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(configMD5Btn),TRUE);
  else
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(configMD5Btn),FALSE);

  if (state & IPMSG_SIGN_SHA1)
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(configSHA1Btn),TRUE);
  else
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(configSHA1Btn),FALSE);

  if (hostinfo_refer_ipmsg_crypt_policy_is_speed())
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(keySelectAlgoCBtn),TRUE);
  else
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(keySelectAlgoCBtn),FALSE);

  if (hostinfo_refer_ipmsg_encrypt_public_key())
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(RSAKeyEncryptionCBtn),TRUE);
  else
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(RSAKeyEncryptionCBtn),FALSE);
  if (hostinfo_refer_ipmsg_use_lock())
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(useLockCBtn),TRUE);
  else
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(useLockCBtn),FALSE);

  return configWindow;
}

int 
apply_crypt_config_window(GtkWindow *configWindow){
  int rc;
  GtkWidget *sendHostListChkBtn;
  GtkWidget *obtainHostlistChkBtn;
  GtkWidget *configRC2Bit40Btn;
  GtkWidget *configRC2Bit128Btn;
  GtkWidget *configRC2Bit256Btn;
  GtkWidget *configBFBit128Btn;
  GtkWidget *configBFBit256Btn;
  GtkWidget *configRSABit512Btn;
  GtkWidget *configRSABit1024Btn;
  GtkWidget *configRSABit2048Btn;
  GtkWidget *configMD5Btn;
  GtkWidget *configSHA1Btn;
  GtkWidget *keySelectAlgoCBtn;
  GtkWidget *RSAKeyEncryptionCBtn;
  GtkWidget *useLockCBtn;
  unsigned long state;
  
  if (!configWindow)
    return -EINVAL;

  sendHostListChkBtn=lookup_widget(GTK_WIDGET(configWindow),"sendHostListChkBtn");
  obtainHostlistChkBtn=lookup_widget(GTK_WIDGET(configWindow),"obtainHostlistChkBtn");
  configRC2Bit40Btn=lookup_widget(GTK_WIDGET(configWindow),"configRC2Bit40Btn");
  configRC2Bit128Btn=lookup_widget(GTK_WIDGET(configWindow), "configRC2Bit128Btn");
  configRC2Bit256Btn=lookup_widget(GTK_WIDGET(configWindow), "configRC2Bit256Btn");
  configBFBit128Btn=lookup_widget(GTK_WIDGET(configWindow), "configBFBit128Btn");
  configBFBit256Btn=lookup_widget(GTK_WIDGET(configWindow), "configBFBit256Btn");
  configRSABit512Btn=lookup_widget(GTK_WIDGET(configWindow), "configRSABit512Btn");
  configRSABit1024Btn=lookup_widget(GTK_WIDGET(configWindow), "configRSABit1024Btn");
  configRSABit2048Btn=lookup_widget(GTK_WIDGET(configWindow), "configRSABit2048Btn");
  configMD5Btn=lookup_widget(GTK_WIDGET(configWindow), "configMD5Btn");
  configSHA1Btn=lookup_widget(GTK_WIDGET(configWindow), "configSHA1Btn");
  keySelectAlgoCBtn=lookup_widget(GTK_WIDGET(configWindow), "keySelectAlgoCBtn");
  RSAKeyEncryptionCBtn=lookup_widget(GTK_WIDGET(configWindow), "RSAKeyEncryptionCBtn");
  useLockCBtn=lookup_widget(GTK_WIDGET(configWindow), "useLockCBtn");

  /*
   *ホストリスト制御
   */
  hostinfo_set_ipmsg_is_allow_hlist(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sendHostListChkBtn))); 
  hostinfo_set_ipmsg_is_get_hlist(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(obtainHostlistChkBtn)));

  /*
   *暗号選択
   */

  /*
   * 共通鍵
   */
  state=0;
  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(configRC2Bit40Btn)))
    state |= IPMSG_RC2_40;
  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(configRC2Bit128Btn)))
    state |= IPMSG_RC2_128;
  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(configRC2Bit256Btn)))
    state |= IPMSG_RC2_256;

  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(configBFBit128Btn)))
    state |= IPMSG_BLOWFISH_128;
  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(configBFBit256Btn)))
    state |= IPMSG_BLOWFISH_256;

  /*
   * RSA
   */
  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(configRSABit512Btn)))
    state |= IPMSG_RSA_512;
  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(configRSABit1024Btn)))
    state |= IPMSG_RSA_1024;
  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(configRSABit2048Btn)))
    state |= IPMSG_RSA_2048;

  /*
   * 署名
   */
  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(configMD5Btn)))
    state |= IPMSG_SIGN_MD5;
  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(configSHA1Btn)))
    state |= IPMSG_SIGN_SHA1;

  hostinfo_set_ipmsg_cipher(state);

  /*
   * セキュリティ設定
   */
  hostinfo_set_ipmsg_crypt_policy_as_speed(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(keySelectAlgoCBtn)));
  hostinfo_set_ipmsg_encrypt_public_key(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(RSAKeyEncryptionCBtn)));
  hostinfo_set_ipmsg_use_lock(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(useLockCBtn)));

  return 0;
}
static int
enter_password(void){
  int rc;
  GtkWidget *window=NULL;
  gint result;

  window=create_passwdWindow();
  g_assert(window);

  
  return 0;
}
